<template>
    <div class="app-container">
        <div ref="gantt" class="left-container" />
        <button @click="handleGetData">获取数据</button>
        <button @click="handleClearData">清除数据</button>
    </div>
</template>
<script>
import gantt from 'dhtmlx-gantt'  // 引入模块
//import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
import 'dhtmlx-gantt/codebase/skins/dhtmlxgantt_terrace.css' //皮肤
import 'dhtmlx-gantt/codebase/locale/locale_cn'  // 本地化
import 'dhtmlx-gantt/codebase/ext/dhtmlxgantt_tooltip.js' //任务条悬浮提示
import localStroage from '../utils/localStroage.js'
const { setStroage, getStroage } = localStroage;
function formatDate(date) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
}

export default {
    // eslint-disable-next-line
    name: 'gantt',
    data() {
        return {
            optionType:'新建',
            tasks: {
                data: [],
                links: [
                    // {
                    //     "source": "1703827887099",
                    //     "target": "1703827939422",
                    //     "type": "1"
                    // }
                ],
            }
        }
    },
    created() {
        if (getStroage('task')) {
            // 默认全部展开
            this.tasks.data = getStroage('task').map(item =>{
                return {
                    ...item,
                    open:true
                }
            });
        }
        if (getStroage('links')) {
            this.tasks.links = getStroage('links')
        }
    },
    methods: {
        //开始时间-结束时间参数
        DateDifference: function (strDateStart, strDateEnd) {
            var begintime_ms = Date.parse(new Date(strDateStart.replace(/-/g, '/'))) //begintime 为开始时间
            var endtime_ms = Date.parse(new Date(strDateEnd.replace(/-/g, '/')))   // endtime 为结束时间
            var date3 = endtime_ms - begintime_ms //时间差的毫秒数
            var days = Math.floor(date3 / (24 * 3600 * 1000))
            return days
        },
        // 初始化数据
        initData: function () {
            // toolTipsTxt: '长文字提示'

            // this.tasks.data = [
            //     {
            //         id: 1,
            //         text: '计划时间',
            //         start_date: '2020-04-08',
            //         duration: 10,
            //         open: true, //默认打开，
            //     },
            //     {
            //         text: '冒烟阶段', // 任务名
            //         start_date: '2020-04-08', // 开始时间
            //         id: 11, // 任务id
            //         duration: 3, // 任务时长，从start_date开始计算
            //         parent: 1, // 父任务ID
            //         type: 1
            //     },
            //     {
            //         text: '单元测试', // 任务名
            //         start_date: '2020-04-11', // 开始时间
            //         id: 12, // 任务id
            //         duration: 2, // 任务时长，从start_date开始计算
            //         parent: 1, // 父任务ID
            //         type: 2

            //     },
            //     {
            //         text: '回归测试', // 任务名
            //         start_date: '2020-04-13', // 开始时间
            //         id: 13, // 任务id
            //         duration: 4, // 任务时长，从start_date开始计算
            //         parent: 1, // 父任务ID
            //         type: 3

            //     }, {
            //         text: '阶段四', // 任务名
            //         start_date: '2020-04-13', // 开始时间
            //         id: 14, // 任务id
            //         duration: 4, // 任务时长，从start_date开始计算
            //         parent: 1, // 父任务ID
            //         type: 4

            //     },
            //     //========================
            //     {
            //         id: 2,
            //         text: '实际时间',
            //         start_date: '2020-04-08',
            //         duration: 8,
            //         open: true, //默认打开，才可隐藏左侧表格
            //         state: 'default'
            //         // color:"#409EFF",
            //         //progress: 0.6
            //     },
            //     {
            //         text: '冒烟阶段', // 任务名
            //         start_date: '2020-04-08', // 开始时间
            //         id: 21, // 任务id
            //         duration: 2, // 任务时长，从start_date开始计算
            //         parent: 2, // 父任务ID
            //         type: 1
            //     },
            //     {
            //         text: '单元测试', // 任务名
            //         start_date: '2020-04-09', // 开始时间
            //         id: 22, // 任务id
            //         duration: 2, // 任务时长，从start_date开始计算
            //         parent: 2, // 父任务ID
            //         type: 2
            //     },
            //     {
            //         text: '回归测试', // 任务名
            //         start_date: '2020-04-11', // 开始时间
            //         id: 23, // 任务id
            //         duration: 2, // 任务时长，从start_date开始计算
            //         parent: 2, // 父任务ID
            //         type: 3
            //     }
            //     // eslint-disable-next-line
            // ]

            // .map(function (current, ind, arry) {
            //     var newObj = {}
            //     if (current.type) { //存在type字段 说明非一级菜单，判断阶段的具体类型 设置不同颜色
            //         if (current.type == 1) { //冒烟
            //             newObj = Object.assign({}, current, { 'color': '#fcca02' })
            //         } else if (current.type == 2) { //单元
            //             newObj = Object.assign({}, current, { 'color': '#fec0dc' })
            //         } else if (current.type == 3) { //回归
            //             newObj = Object.assign({}, current, { 'color': '#62ddd4' })
            //         } else if (current.type == 4) {
            //             newObj = Object.assign({}, current, { 'color': '#d1a6ff' })
            //         }
            //     } else { //一级菜单是蓝色的
            //         newObj = Object.assign({}, current, { 'color': '#5692f0' })
            //     }

            //     return newObj
            // })
            // this.tasks.data.map(function (current) {
            //     var newObj = {}
            //     newObj = Object.assign({}, current, { 'color': '#5692f0' })
            //     return newObj;
            // })
        },
        // 获取数据
        handleGetData() {
            var allData = gantt.serialize(); // 获取当前所有数据
            console.log(allData)
            // 通过接口将所有数据持久化
            // 例如：使用 fetch 或 axios 发送 POST 请求将数据提交至后端
        },
        // 清除数据
        handleClearData(){
            window.localStorage.clear()
            window.location.reload()
        }
    },
    mounted() {
        this.initData()
        const _this = this;

        // 任务视图单进度条右侧描述
        // gantt.templates.rightside_text = function (start, end, task) {
		//     return "ID: #" + task.id;
        // };

        // 任务视图单进度条左侧描述
        gantt.templates.leftside_text = function (start, end, task) {
            return task.duration + " days";
        };
        
        // 点击表头可排序
        gantt.config.sort = true;
        /*
        * 冒烟：fcca02    单元：fec0dc     回归：62ddd4   阶段：d1a6ff
        * */
        //设置图表区域的日期坐标最大值 var date = new Date(dateString.replace(/-/,"/"))
        //  gantt.config.start_date = new Date("2020-04-08".replace(/-/,"/")) ;
        // gantt.config.end_date = new Date("2020-04-18".replace(/-/,"/")) ; //结束时间需要+1天
        //自适应甘特图的尺寸大小, 使得在不出现滚动条的情况下, 显示全部任务
        gantt.config.autosize = true
        //只读模式
        gantt.config.readonly = false // 是否可以设置
        //是否显示左侧树表格
        gantt.config.show_grid = true // 是否显示树结构
        //表格列设置 设置之后不可以添加编辑
        // gantt.config.columns = [
        //     { name: 'text', label: '阶段名字', tree: true, width: '160' },
        //     {
        //         name: 'duration', label: '时长', align: 'center', template: function (obj) {
        //             return obj.duration + '天'
        //         }
        //     },
        // ]
        //时间轴图表中，如果不设置，只有行边框，区分上下的任务，设置之后带有列的边框，整个时间轴变成格子状。
        gantt.config.show_task_cells = true

        //是否显示依赖连线
        gantt.config.show_links = true;

        //设置x轴日期
        gantt.config.scale_unit = 'day'
        // 设置步长
        gantt.config.step = 1
        // 设置右侧显示日期格式
        // gantt.config.date_scale = '星期' + '%D'
        gantt.config.date_scale = '%M' + '%d' + '日' + '(星期' + '%D' + ')'
            
        // 设置甘特图时间的起始结束时间，并允许显示超过时间刻度任务
        gantt.config.show_tasks_outside_timescale = true

        //当task的长度改变时，自动调整图表坐标轴区间用于适配task的长度
        gantt.config.fit_tasks = true
        // 在时间线上增加一行显示星期
        // 合并到date_scale，添加自定义多行的时候添加week只生效一行
        // gantt.config.subscales = [
        // {unit:"day",  step:1, date:"星期"+"%D" },
        // { unit: 'day', step: 1, date: '%M' + '%d' + '日' }
        // ]
        // 任务栏 + 甘特图 表头的高度
        gantt.config.scale_height = 46; 
        //时间轴图表中，任务条形图的高度
        gantt.config.task_height = 36
        //时间轴图表中，甘特图的高度
        gantt.config.row_height = 36
        //从后端过来的数据格式化
        gantt.config.xml_date = '%Y-%m-%d'
        // gantt.config.xml_date = "%Y-%m-%d %H:%i";
        
        //任务条显示内容
        gantt.templates.task_text = function (start, end, task) {
            return task.text + '(' + task.duration + '天)'
        }
        // gantt内置弹出框的内容 头部自定义
        gantt.templates.lightbox_header = function (start_date, end_date, task) {
            return `<b>${task.text}</b>`
        };
        // 添加右侧任务栏类名
        gantt.templates.task_class = function(start, end, task){
            // if (task.progress == 1) {
            //     return "completed-task"; // 添加自定义 CSS 类名
            // } else {
            //     return ""; // 默认情况下没有自定义 CSS 类名
            // }
        };
        //悬浮
        // eslint-disable-next-line
        gantt.templates.tooltip_text = function (start, end, task) {
            //return "<b>任务名称:</b> "+task.text+"<br/><b>时长:</b> " + task.duration+"<br/><b>说明:</b>" +task.toolTipsTxt;
            return task.toolTipsTxt && '<span style=\'font-size: 14px\'>' + task.toolTipsTxt + '</span>'
        }
        //任务栏周末亮色
        gantt.templates.scale_cell_class = function (date) {
            if (date.getDay() == 0 || date.getDay() == 6) {
                return "weekend";
            }
        };
        gantt.templates.timeline_cell_class = function (item, date) {
            if (date.getDay() == 0 || date.getDay() == 6) {
                return "weekend"
            }
        };
      
        // 监听任务新增事件
        gantt.attachEvent("onAfterTaskAdd", function (id, item) {
            console.log(id)
            console.log(item)
            const postData = {
                id: item.id,
                parent: item.parent,
                text: item.text,
                progress: 0,
                start_date: formatDate(new Date(item.start_date)),
                end_date: formatDate(new Date(item.end_date)),
                duration: item.duration,
                open: false,
            }
            console.log(postData)
            // add 
            if (getStroage('task')) {
                const localTask = getStroage('task');
                localTask.push(postData)
                setStroage('task', localTask)
                // this.tasks.data = localTask;
            } else {
                setStroage('task', [].concat(postData))
            }
        });

        // 监听设置任务的最小进度
        gantt.attachEvent("onBeforeTaskUpdate", function (id, task) {
            if (task.progress < 0.01) {
                task.progress = 0.01; // 将进度设置为0.1
            }
            return true; // 返回true以允许任务更新，或返回false以禁止更新
        });


        // 监听任务修改事件
        gantt.attachEvent("onAfterTaskUpdate", function (id, item) {
            console.log(id)
            console.log(item)
            const postData = {
                id: item.id,
                parent: item.parent,
                text: item.text,
                progress: item.progress,
                start_date: formatDate(new Date(item.start_date)),
                end_date: formatDate(new Date(item.end_date)),
                duration: item.duration,
                open: false,
            }

            if (getStroage('task')) {
                const localTask = getStroage('task');
                const index = localTask.findIndex(taskItem => taskItem.id === id);
                localTask.splice(index, 1, postData)
                setStroage('task', localTask)
            }
        });


        // 监听任务删除事件 onAfterTaskDelete onBeforeTaskDelete
        gantt.attachEvent("onAfterTaskDelete", function (id) {
            if (getStroage('task')) {
                const localTask = getStroage('task');
                const index = localTask.findIndex(taskItem => taskItem.id === id);
                localTask.splice(index, 1)
                setStroage('task', localTask)
            }
        });
        // links 新增
        gantt.attachEvent("onLinkCreated", function(link) {
            if (getStroage('links')) {
                const localTask = getStroage('links');
                localTask.push(link)
                setStroage('links', localTask)
            } else {
                setStroage('links', [].concat(link))
            }
            return true;
        });

        // links 修改
        gantt.attachEvent("onAfterLinkUpdate", function(link) {
            console.log(link)
            return true;
        });

        // links 删除
        gantt.attachEvent("onAfterLinkDelete", function (id) {
            if (getStroage('links')) {
                const localTask = getStroage('links');
                const index = localTask.findIndex(linksItem => linksItem.id === id);
                localTask.splice(index, 1)
                setStroage('links', localTask)
            }
            return true;
        });

        // 初始化
        gantt.init(this.$refs.gantt);
        // 数据解析
        gantt.parse(this.tasks)
        // setInterval(()=>{
        //     console.table(this.tasks.data)
        // },5000)
    }
}

// 参考文章 https://www.inte.net/news/276765.html
</script>
<style >
.thirdLevelTask {
    border: 2px solid #da645d;
    color: #da645d;
    background: #da645d;
}

.milestone-default {
    border: none;
    background: rgba(0, 0, 0, 0.45);
}

.milestone-unfinished {
    border: none;
    background: #5692f0;
}

.milestone-finished {
    border: none;
    background: #84bd54;
}

.milestone-canceled {
    border: none;
    background: #da645d;
}

html,
body {
    margin: 0px;
    padding: 0px;
    height: 100%;
    overflow: hidden;
}

.container {
    height: 900px;

    .left-container {
        height: 100%;
    }
}

.left-container {
    height: 600px;
}

.gantt_scale_line {
    border-top: 0;
}

.weekend {
    background: #f4f7f4;
}

.gantt_selected .weekend {
    background: #f7eb91;
}

.gantt_task_content {
    text-align: left;
    padding-left: 10px;
}

.completed-task {
    background-color: #93D67B !important; /* 设置已完成任务的背景颜色 */
}
/* .gantt_task_line{
    border: 3px solid #6ba8e3;
    background: #6ba8e3;
}
.gantt_task_progress{
    background: #5498dd;
} */
</style>
  